package com.csjy.migration.hnnd.business;

import com.csjy.migration.hnnd.*;
import com.csjy.migration.hnnd.annotation.BusinessDataConverter;
import com.csjy.migration.hnnd.dict.ChargeType;

import javax.script.ScriptException;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

@BusinessDataConverter(
    auto = false,
    insertSql = "INSERT INTO ND_BPM_FEE_COLLECTION_RECORD" +
        "(ID, CREATE_NAME, CREATE_BY, CREATE_DATE, UPDATE_NAME, UPDATE_BY, UPDATE_DATE, SYS_ORG_CODE, SYS_COMPANY_CODE, BPM_STATUS, PRO_ID, CHARGE_TYPE, RETREAT_TYPE, AMOUNT_RECEIVABLE, AMOUNT_MONEY, PAY_ACCOUNT, CHARGE_TIME, REFUND_TIME, REMARK, EXPLANATION, PROC_ID, TASK_ID, IS_VALID, TASK_DEF_KEY, SOURCE_ID, PAYMENT_ACCOUNT, PAYMENT_TIME, PAYMENT_BANK, CHARGE_TAG, PAYMENT_BANK_SUBBRANCH, TAX_RATE)" +
        "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n",
    updateSql = "UPDATE ND_BPM_FEE_COLLECTION_RECORD \n" +
        "SET CREATE_NAME=?, CREATE_BY=?, CREATE_DATE=?, UPDATE_NAME=?, UPDATE_BY=?, UPDATE_DATE=?, SYS_ORG_CODE=?, SYS_COMPANY_CODE=?, BPM_STATUS=?, PRO_ID=?, CHARGE_TYPE=?, RETREAT_TYPE=?, AMOUNT_RECEIVABLE=?, AMOUNT_MONEY=?, PAY_ACCOUNT=?, CHARGE_TIME=?, REFUND_TIME=?, REMARK=?, EXPLANATION=?, PROC_ID=?, TASK_ID=?, IS_VALID=?, TASK_DEF_KEY=?, SOURCE_ID=?, PAYMENT_ACCOUNT=?, PAYMENT_TIME=?, PAYMENT_BANK=?, CHARGE_TAG=?, PAYMENT_BANK_SUBBRANCH=?, TAX_RATE=?\n" +
        "WHERE ID = ?",
    findMigratedIdListSql = "SELECT ID FROM ND_BPM_FEE_COLLECTION_RECORD WHERE PROC_ID = ?"
)
public class NdBpmFeeCollectionRecord extends AbstractWorkflowBusiness {

  private boolean filterByTaskId = false;

  public NdBpmFeeCollectionRecord(DbUtil sourceDbUtil, DbUtil targetDbUtil, SourceBusinessData sourceData, ProgramArgument programArgument, String projectId, String procInstId) throws SQLException {
    super(sourceDbUtil, targetDbUtil, sourceData, programArgument, projectId, procInstId);
  }

  public NdBpmFeeCollectionRecord(DbUtil sourceDbUtil, DbUtil targetDbUtil, SourceBusinessData sourceData, ProgramArgument programArgument, String projectId, String procInstId, boolean filterByTaskId) throws SQLException {
    super(sourceDbUtil, targetDbUtil, sourceData, programArgument, projectId, procInstId);
    this.filterByTaskId = filterByTaskId;
  }

  @Override
  public void migrate() throws Exception {

    // TODO: sort by sortNo
    List<Map> btItemChargeAuditList = this.sourceData.getBtItemChargeAuditList().stream()
        .filter(btItemAccountDetail->{
          if(btItemAccountDetail.get("PROCID") == null){
            return false;
          }
          return btItemAccountDetail.get("PROCID").toString().equals(this.procInstId);
        })
        .collect(Collectors.toList());

    for(Map.Entry<String,Map<String,Object>> entry : taskParamMap.entrySet()) {
      String curJbpmTaskInstanceId = entry.getKey();
      Map<String,Object> taskParam = entry.getValue();

      for (Map row : btItemChargeAuditList) {
        try {
          // 根据任务id过滤
          if(filterByTaskId && row.get("TASKID") != null) {
            if(!row.get("TASKID").toString().equals(curJbpmTaskInstanceId)) {
              continue;
            }
          }
          // 判断是否需要覆盖迁移
          int needMigratedResult = this.needMigrated(this.procInstId + "-"+ curJbpmTaskInstanceId + "-"+ (row.get("SORTNO")== null ? "": row.get("SORTNO").toString()));
          if(needMigratedResult == 0) {
            continue;
          }

          // 单条插入或更新
          if(needMigratedResult == 1) {
            this.targetDbUtil.updateByParams(updateSql,this.buildValues(row, curJbpmTaskInstanceId, taskParam),true);
            // 批量插入或更新 和 单条插入或更新 二选一
//            this.batchUpdateValues.add(this.buildValues(row, curJbpmTaskInstanceId, taskParam));
          } else {
            this.targetDbUtil.updateByParams(insertSql,this.buildValues(row, curJbpmTaskInstanceId, taskParam));
            // 批量插入或更新 和 单条插入或更新 二选一
//            this.batchInsertValues.add(this.buildValues(row, curJbpmTaskInstanceId, taskParam));
          }
        } catch(Exception e) {
          throw new Exception(String.format("流程实例[%s]-任务实例[%s]-收费退费数据迁移失败:%s\n",this.procInstId, curJbpmTaskInstanceId, e.getMessage()));
        }
      }
    }
  }

  public List buildValues(Map row, String curJbpmTaskInstanceId, Map<String,Object> taskParam) throws ScriptException, SQLException {
    List values = new ArrayList();
    // ID
    values.add(this.procInstId + "-"+ curJbpmTaskInstanceId + "-"+row.get("SORTNO"));
    // CREATE_NAME
    values.add(null);
    // CREATE_BY
    values.add(row.get("SUBMITEMP"));
    // CREATE_DATE
    values.add(row.get("CREATE_TIME"));
    // UPDATE_NAME
    values.add(null);
    // UPDATE_BY
    values.add(null);
    // UPDATE_DATE
    values.add(row.get("MODIFY_TIME"));
    // SYS_ORG_CODE
    values.add(null);
    // SYS_COMPANY_CODE
    values.add("002");
    // BPM_STATUS
    values.add(1);
    // PRO_ID
    values.add(this.projectId);
    // CHARGE_TYPE 费用类型
    values.add(DictTool.getTargetDictCode(ChargeType.class,row.get("FEETYPE")));
    // RETREAT_TYPE 收费：charge 退费: refund
    values.add(row.get("IOTYPE").toString().equals("2") ? "refund" : "charge");
    // AMOUNT_RECEIVABLE 应收款
    values.add(row.get("OUGHTSUM"));
    // AMOUNT_MONEY 实收额
    values.add(row.get("DEALSUM"));
    // PAY_ACCOUNT 付款户名
    values.add(row.get("PAYMENTNAME"));
    // CHARGE_TIME 入账时间
    values.add(row.get("DEALTIME"));
    // REFUND_TIME
    values.add(row.get("DEALTIME"));
    // REMARK
    values.add(Tool.decodeUnicode(row.get("DEALMARK")));
    // EXPLANATION
    values.add(Tool.decodeUnicode(row.get("FAVORMARK")));
    // PROC_ID
    values.add(this.procInstId + "-JW") ;
    // TASK_ID
    values.add(curJbpmTaskInstanceId + "-JW") ;
    // IS_VALID
    values.add("Y");
    // TASK_DEF_KEY
    values.add(taskParam.get("taskDefKey"));
    // TODO:SOURCE_ID
    values.add(null);
    // PAYMENT_ACCOUNT
    values.add(row.get("PAYMENTNAME"));
    // PAYMENT_TIME 付款时间
    values.add(row.get("DEALTIME"));
    // PAYMENT_BANK 付款银行
    values.add(null);
    // CHARGE_TAG
    values.add(1);
    // PAYMENT_BANK_SUBBRANCH 分支银行名称
    values.add(null);
    // TAX_RATE 费率
    values.add(null);
    return values;
  }
}
